home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.2 Applications 1996 May / SGI IRIX 6.2 Applications 1996 May.iso / dist / impr_dev.idb / usr / impressario / src / gui_models / laserjetPJL / util.c.z / util.c
C/C++ Source or Header  |  1996-05-06  |  41KB  |  1,505 lines

  1. /**************************************************************************
  2.  *
  3.  *           Copyright (c)    1993 Silicon Graphics, Inc.
  4.  *
  5.  * Permission to use, copy, modify, distribute, and sell this software and
  6.  * its documentation for any purpose is hereby granted without fee, provided
  7.  * that (i) the above copyright notices and this permission notice appear in
  8.  * all copies of the software and related documentation, and (ii) the name of
  9.  * Silicon Graphics may not be used in any advertising or publicity relating
  10.  * to the software without the specific, prior written permission of Silicon
  11.  * Graphics.
  12.  * 
  13.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  16.  *
  17.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  18.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
  19.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
  20.  * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
  21.  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * SILICON GRAPHICS RESERVES THE RIGHT TO CHANGE FUTURE VERSIONS OF THIS
  24.  * SOFTWARE IN ANY MANNER AND AT ANY TIME WITHOUT PRIOR NOTICE.
  25.  *
  26.  **************************************************************************
  27.  *
  28.  * File: util.c
  29.  *
  30.  * Note to Developer: This file requires no modification.
  31.  *
  32.  * Description: Utility functions for the graphical model file program.
  33.  *
  34.  **************************************************************************/
  35.  
  36.  
  37. #ident "$Revision: 1.7 $"
  38.  
  39.  
  40. #include <stdio.h>
  41. #include <string.h>
  42. #include <stdlib.h>
  43. #include <stdarg.h>
  44. #include <ctype.h>
  45. #include <sys/types.h>
  46. #include <Xm/Xm.h>
  47. #include <X11/StringDefs.h>
  48. #include <Xm/Form.h>
  49. #include <Xm/RowColumn.h>
  50. #include <Xm/PushB.h>
  51. #include <Xm/Label.h>
  52. #include <Xm/Text.h>
  53. #include <Xm/TextF.h>
  54. #include <Xm/ToggleB.h>
  55. #include <Xm/BulletinB.h>
  56. #include "xutil.h"
  57.  
  58. #include "util.h"
  59.  
  60.  
  61. /* File specific layout constants */
  62.  
  63. #define OPTIONS_INDENT          5
  64. #define TEXT_FIELD_MAR          2
  65.  
  66. /* No resource defaults */
  67.  
  68. #define DEF_INSENSITIVE_BACK    "gray72"
  69. #define DEF_INSENSITIVE_FORE    "gray50"
  70.  
  71.  
  72. /* Text field color struct */
  73.  
  74. typedef struct {
  75.     Pixel foreground;        /* Foreground color */
  76.     Pixel background;           /* Background color */
  77.     Pixel tshadow;              /* Top shadow color */
  78.     Pixel bshadow;              /* Bottom shadow color */
  79. } GUIColor;
  80.  
  81.  
  82. /* Program scope globals */
  83.  
  84. char *progName;
  85. AppData gmodelResources;
  86. PDInfoStruct *podInfo;
  87.  
  88. static Widget helpPane = NULL;       /* Help pane */
  89.  
  90. /* Gmodel specific resource list */
  91.  
  92. static XtResource resources[] = {
  93.         /* Insensitive background */
  94.         {
  95.         GmdlNinsensitiveBackground, GmdlCInsensitiveBackground,
  96.     XtRPixel, sizeof(Pixel),
  97.         XtOffsetOf(AppData, insensitiveBack), XtRString,
  98.     (XtPointer)DEF_INSENSITIVE_BACK
  99.         },
  100.         /* Insensitive foreground */
  101.         {
  102.         GmdlNinsensitiveForeground, GmdlCInsensitiveForeground,
  103.     XtRPixel, sizeof(Pixel),
  104.         XtOffsetOf(AppData, insensitiveFore), XtRString,
  105.     (XtPointer)DEF_INSENSITIVE_FORE
  106.         },
  107. };
  108.  
  109. /**************************************************************************
  110.  *
  111.  * Function: createHelpWindow
  112.  *
  113.  * Description: Creates a small window for help text to be displayed
  114.  *      in.  Help text changes as user moves his cursor over fields on
  115.  *      the more options screen.
  116.  *
  117.  * Parameters:
  118.  *      widget (I) - any widget
  119.  *
  120.  * Return: none
  121.  *
  122.  **************************************************************************/
  123.  
  124. Widget createHelpWindow(Widget parent)
  125. {
  126.     char *str;
  127.     Pixel background;
  128.     DEFARGS(5);
  129.  
  130.     str=GetResourceString(parent,"DisplayHelpString",
  131.                           (char*) XtName(parent),"");
  132.  
  133.     if ( str && !strncasecmp(str,"True",4) ) {
  134.  
  135.         STARTARGS;
  136.         SETARG(XmNbackground, &background);
  137.         XtGetValues(parent, ARGLIST);
  138.  
  139.         helpPane = XmCreateText(parent, "helpPane", NULL, 0);
  140.         XtVaSetValues(helpPane,
  141.                       XmNalignment,         XmALIGNMENT_BEGINNING,
  142.                       XmNeditable,          False,
  143.                       XmNborderWidth,       1,
  144.                       XmNshadowThickness,   1,
  145.                       XmNbackground,        background, 
  146.                       XmNeditMode,          XmMULTI_LINE_EDIT,
  147.                       XmNwordWrap,          True,
  148.                       XmNrows,              3,
  149.                       NULL);
  150.  
  151.         XtManageChild(helpPane);
  152.  
  153.         str=
  154.         GetResourceString(helpPane,"helpString",(char*) XtName(helpPane),"");
  155.         XtAddEventHandler(helpPane, 
  156.                           (EventMask) (EnterWindowMask|LeaveWindowMask),
  157.                           False, (XtEventHandler) HelpCB, str);
  158.  
  159.  
  160.     }
  161.     return helpPane;
  162.  
  163. }
  164.  
  165. /**************************************************************************
  166.  *
  167.  * Function: getAppResources
  168.  *
  169.  * Description: Reads the gmodel specific resources fromthe app-defaults
  170.  *    file. The function fills in the fields in the gmodelResources
  171.  *    structure which is globally available to all program modules.
  172.  *
  173.  * Parameters: 
  174.  *    widget (I) - any widget
  175.  *
  176.  * Return: none
  177.  *
  178.  **************************************************************************/
  179.  
  180. void getAppResources(Widget widget)
  181. {
  182.     XtGetApplicationResources(widget, (XtPointer)&gmodelResources,
  183.                 resources, XtNumber(resources), NULL, 0);
  184. }
  185.  
  186.  
  187. /**************************************************************************
  188.  *
  189.  * Function: makeArgs
  190.  *
  191.  * Description: Constructs argv list from the specified string of options.
  192.  *
  193.  * Parameters: 
  194.  *    str (I) - string of options to parse
  195.  *    argcp (O) - number of arguments parsed from str
  196.  *    argvp (O) - list of options parsed from str
  197.  *
  198.  * Return: none
  199.  *
  200.  **************************************************************************/
  201.  
  202. void makeArgs(const char *str, int *argcp, char ***argvp)
  203. {
  204.     register char *s, *sptr, *aptr;
  205.     char **av;
  206.     register int ag;
  207.  
  208.     /*
  209.      * Initialize everything
  210.      */
  211.     *argcp = ag = 0;
  212.     *argvp = av = NULL;
  213.  
  214.     /*
  215.      * Don't do anything if there is nothing in the string
  216.      */
  217.     if (!str || *str == '\0')
  218.     return;
  219.  
  220.     /*
  221.      * We will be modifying the string so make a copy to preserve the
  222.      * user's string.
  223.      */
  224.     s = sptr = XtNewString(str);
  225.  
  226.     /*
  227.      * Build the argument list
  228.      */
  229.     while ((aptr = strtok(sptr, " \t")) != NULL) {
  230.     sptr = NULL;
  231.     av = (av) ? (char**)XtRealloc((char*)av, (ag+1) * sizeof(char*)):
  232.                     (char**)XtMalloc(sizeof(char*));
  233.     av[ag++] = XtNewString(aptr);
  234.     }
  235.  
  236.     /*
  237.      * Free the temporary string
  238.      */
  239.     XtFree((char*)s);
  240.  
  241.     /*
  242.      * Set the user variables and return
  243.      */
  244.     *argcp = ag;
  245.     *argvp = av;
  246. }
  247.  
  248.  
  249. /**************************************************************************
  250.  *
  251.  * Function: freeArgs
  252.  *
  253.  * Description: Releases the storage allocated by makeArgs. Can also
  254.  *    be used to free the storage allocated when building any list
  255.  *    of strings where both the strings and the list of pointers
  256.  *    have been dynamically allocated.
  257.  *
  258.  * Parameters: 
  259.  *    argc (I) - number of arguments in list
  260.  *    argv (I) - argument list to deallocate
  261.  *
  262.  * Return: none
  263.  *
  264.  **************************************************************************/
  265.  
  266. void freeArgs(int argc, char **argv)
  267. {
  268.     register int i;
  269.  
  270.     if (!argv)
  271.     return;
  272.     for (i = 0; i < argc; i++)
  273.     XtFree((char*)argv[i]);
  274.     XtFree((char*)argv);
  275. }
  276.  
  277.  
  278. /**************************************************************************
  279.  *
  280.  * Function: createOptionPanel
  281.  *
  282.  * Description: Sets up a generic panel for option switches.
  283.  *
  284.  * Parameters: 
  285.  *    name (I) - instance name for option panel
  286.  *    parent (I) - parent widget ID
  287.  *
  288.  * Return: Manager widget ID for option objects.
  289.  *
  290.  **************************************************************************/
  291.  
  292. Widget createOptionPanel(char *name, Widget parent)
  293. {
  294.     Widget form, lbl, bb;
  295.     char *subName;
  296.     char *str;
  297.     DEFARGS(15);
  298.  
  299.     /*
  300.      * Allocate space for instance names.
  301.      */
  302.     subName = (char*)XtMalloc(strlen(name) + 15);
  303.  
  304.     /*
  305.      * Create a form to hold everything
  306.      */
  307.     sprintf(subName, "%sForm", name);
  308.     form = XtCreateManagedWidget(subName, xmFormWidgetClass, parent, NULL, 0);
  309.  
  310.     /*
  311.      * Create the title label for the panel
  312.      */
  313.     STARTARGS;
  314.     SETARG(XmNtopAttachment, XmATTACH_FORM);
  315.     SETARG(XmNleftAttachment, XmATTACH_FORM);
  316.     lbl = XtCreateManagedWidget(name, xmLabelWidgetClass, form, ARGLIST);
  317.  
  318.     /*
  319.      * Add a callback to display a short help message whenever the
  320.      * pointer is focused on the widget.
  321.      */
  322.  
  323.      if (helpPane != NULL) {
  324.          str=GetResourceString(lbl,"helpString",(char*) XtName(lbl),"");
  325.          XtAddEventHandler(lbl, (EventMask) (EnterWindowMask|LeaveWindowMask),
  326.                            False, (XtEventHandler) HelpCB, str);
  327.      }
  328.  
  329.     /*
  330.      * Create a bulletin board. Into this will be placed a form
  331.      * that will actually hold the option objects. The bulleting board
  332.      * allows us to indent the option switches a fixed amount
  333.      */
  334.     sprintf(subName, "%sBB", name);
  335.     STARTARGS;
  336.     SETARG(XmNtopAttachment, XmATTACH_WIDGET);
  337.     SETARG(XmNtopWidget, lbl);
  338.     SETARG(XmNtopOffset, 4);
  339.     SETARG(XmNleftAttachment, XmATTACH_FORM);
  340.     SETARG(XmNrightAttachment, XmATTACH_FORM);
  341.     SETARG(XmNbottomAttachment, XmATTACH_FORM);
  342.     SETARG(XmNmarginHeight, 2);
  343.     SETARG(XmNmarginWidth, 2);
  344.     bb = XtCreateManagedWidget(subName, xmBulletinBoardWidgetClass,
  345.                     form, ARGLIST);
  346.  
  347.     /*
  348.      * Create the option object form
  349.      */
  350.     sprintf(subName, "%sOptForm", name);
  351.     form = XtCreateManagedWidget(subName, xmFormWidgetClass, bb, NULL, 0);
  352.  
  353.     /*
  354.      * Free name storage
  355.      */
  356.     XtFree(subName);
  357.  
  358.     return form;
  359. }
  360.  
  361.  
  362. /**************************************************************************
  363.  *
  364.  * Function: makeTextF
  365.  *
  366.  * Description: Instantiates a text field
  367.  *
  368.  * Parameters: 
  369.  *    name (I) - name for text field
  370.  *    parent (I) - parent widget ID
  371.  *    cols (I) - number of columns
  372.  *    maxLen (I) - max number of characters to allow. Unlimited if 0
  373.  *            specified.
  374.  *
  375.  * Return: Widget ID of newly created text field
  376.  *
  377.  **************************************************************************/
  378.  
  379. Widget makeTextF(char *name, Widget parent, int cols, int maxLen)
  380. {
  381.     DEFARGS(10);
  382.  
  383.     STARTARGS;
  384.     SETARG(XmNcolumns, cols);
  385.     SETARG(XmNmarginHeight, TEXT_FIELD_MAR);
  386.     SETARG(XmNmarginWidth, TEXT_FIELD_MAR);
  387.     if (maxLen) {
  388.         SETARG(XmNmaxLength, maxLen);
  389.     }
  390.     return XtCreateManagedWidget(name, xmTextFieldWidgetClass,
  391.                         parent, ARGLIST);
  392. }
  393.  
  394.  
  395. /**************************************************************************
  396.  *
  397.  * Function: makeRadioB
  398.  *
  399.  * Description: Creates a set of horiontally oriented radio buttons.
  400.  *
  401.  * Parameters: 
  402.  *    name (I) - name for radio button Row Column
  403.  *    parent (I) - parent widget ID
  404.  *    callback (I) - callback procedure
  405.  *    blistp (O) - array of buttons created
  406.  *    label... (I) - button instance name. Last argument must
  407.  *               be NULL.
  408.  *
  409.  * Return:  Widget ID of Row Column containing the radio buttons.
  410.  *
  411.  **************************************************************************/
  412. /* VARARGS */
  413.  
  414. Widget makeRadioB(char *name, Widget parent, XtCallbackProc callback,
  415.                 WidgetList *blistp, ...)
  416. {
  417.     Widget widget, bw;
  418.     va_list labels;
  419.     char *lptr;
  420.     register int button = 0;
  421.     DEFARGS(10);
  422.  
  423.     /*
  424.      * Create the radio Row Column
  425.      */
  426.     STARTARGS;
  427.     SETARG(XmNmarginHeight, 0);
  428.     SETARG(XmNmarginWidth, 0);
  429.     SETARG(XmNorientation, XmHORIZONTAL);
  430.     SETARG(XmNpacking, XmPACK_TIGHT);
  431.     SETARG(XmNspacing, 2 * LABEL_FIELD_SPACE);
  432.     SETARG(XmNentryClass, xmToggleButtonWidgetClass);
  433.     widget = XmCreateRadioBox(parent, name, ARGLIST);
  434.     XtManageChild(widget);
  435.  
  436.     /*
  437.      * Create each radio button instance
  438.      */
  439.     va_start(labels, blistp);
  440.     STARTARGS;
  441.     SETARG(XmNmarginHeight, 0);
  442.     SETARG(XmNmarginWidth, 0);
  443.     while ((lptr = (char*)va_arg(labels, char*)) != NULL) {
  444.         bw = XtCreateManagedWidget(lptr, xmToggleButtonWidgetClass,
  445.                                         widget, ARGLIST);
  446.     if (callback)
  447.         XtAddCallback(bw, XmNvalueChangedCallback, callback,
  448.                             (XtPointer)button);
  449.     button++;
  450.     }
  451.     va_end(labels);
  452.  
  453.     /*
  454.      * If we asked for list of buttons, provide it
  455.      */
  456.     if (blistp) {
  457.     STARTARGS;
  458.     SETARG(XmNchildren, blistp);
  459.     XtGetValues(widget, ARGLIST);
  460.     }
  461.  
  462.     return widget;
  463. }
  464.  
  465.  
  466. /**************************************************************************
  467.  *
  468.  * Function: makeCheckB
  469.  *
  470.  * Description: Creates a set of horiontally oriented check buttons.
  471.  *
  472.  * Parameters: 
  473.  *    name (I) - name for check button Row Column
  474.  *    parent (I) - parent widget ID
  475.  *    callback (I) - callback procedure
  476.  *    blistp (O) - array of buttons created
  477.  *    label... (I) - button instance name. Last argument must
  478.  *               be NULL.
  479.  *
  480.  * Return:  Widget ID of Row Column containing the check buttons.
  481.  *
  482.  **************************************************************************/
  483. /* VARARGS */
  484.  
  485. Widget makeCheckB(char *name, Widget parent, XtCallbackProc callback,
  486.                 WidgetList *blistp, ...)
  487. {
  488.     Widget widget, bw;
  489.     va_list labels;
  490.     char *lptr;
  491.     register int button = 0;
  492.     DEFARGS(10);
  493.  
  494.     /*
  495.      * Create the check box Row Column
  496.      */
  497.     STARTARGS;
  498.     SETARG(XmNmarginHeight, 0);
  499.     SETARG(XmNmarginWidth, 0);
  500.     SETARG(XmNorientation, XmHORIZONTAL);
  501.     SETARG(XmNpacking, XmPACK_TIGHT);
  502.     SETARG(XmNspacing, 2 * LABEL_FIELD_SPACE);
  503.     SETARG(XmNentryClass, xmToggleButtonWidgetClass);
  504.     SETARG(XmNradioBehavior, False);
  505.     SETARG(XmNradioAlwaysOne, False);
  506.     widget = XmCreateRadioBox(parent, name, ARGLIST);
  507.     XtManageChild(widget);
  508.  
  509.     /*
  510.      * Create each radio button instance
  511.      */
  512.     va_start(labels, blistp);
  513.     STARTARGS;
  514.     SETARG(XmNmarginHeight, 0);
  515.     SETARG(XmNmarginWidth, 0);
  516.     SETARG(XmNindicatorType, XmN_OF_MANY);
  517.     while ((lptr = (char*)va_arg(labels, char*)) != NULL) {
  518.         bw = XtCreateManagedWidget(lptr, xmToggleButtonWidgetClass,
  519.                                         widget, ARGLIST);
  520.     if (callback)
  521.         XtAddCallback(bw, XmNvalueChangedCallback, callback,
  522.                             (XtPointer)button);
  523.     button++;
  524.     }
  525.     va_end(labels);
  526.  
  527.     /*
  528.      * If we asked for list of buttons, provide it
  529.      */
  530.     if (blistp) {
  531.     STARTARGS;
  532.     SETARG(XmNchildren, blistp);
  533.     XtGetValues(widget, ARGLIST);
  534.     }
  535.  
  536.     return widget;
  537. }
  538.  
  539.  
  540. /**************************************************************************
  541.  *
  542.  * Function: makeOptionB
  543.  *
  544.  * Description: Creates an option button and its menu.
  545.  *
  546.  * Parameters: 
  547.  *    name (I) - name for option Row Column 
  548.  *    parent (I) - parent widget ID
  549.  *    callback (I) - callback procedure
  550.  *    blistp (O) - array of buttons created
  551.  *    labels (I) - menu item labels
  552.  *    numLabels (I) - number of labels
  553.  *    incr (I) - amount to increment through the label list. This allows us
  554.  *            to pass arrays of structures and access the string
  555.  *            members.
  556.  *
  557.  * Return: Widget ID of Row Column containing the option button.
  558.  *
  559.  ******************************************************* *******************/
  560.  
  561. Widget makeOptionB(char *name, Widget parent, XtCallbackProc callback,
  562.                 WidgetList *blistp, char **labels,
  563.                 register int numLabels, register int incr)
  564. {
  565.     Widget menuPane, optionRC, optionLabel, bw;
  566.     register int i, offset;
  567.     register int button = 0;
  568.     DEFARGS(5);
  569.  
  570.     /*
  571.      * Create the menu pane
  572.      */
  573.     menuPane = XmCreatePulldownMenu(parent, "optionPane", NULL, 0);
  574.  
  575.     /*
  576.      * Create menu buttons
  577.      */
  578.     for (i = 0, offset = 0; i < numLabels; i++, offset += incr) {
  579.         bw = XtCreateManagedWidget(*(char**)((paddr_t)labels+offset),
  580.                 xmPushButtonWidgetClass, menuPane, NULL, 0);
  581.     if (callback)
  582.         XtAddCallback(bw, XmNactivateCallback, callback,
  583.                             (XtPointer)button);
  584.     button++;
  585.     }
  586.  
  587.     /*
  588.      * Create the option button RowColumn
  589.      */
  590.     STARTARGS;
  591.     SETARG(XmNsubMenuId, menuPane);
  592.     optionRC = XmCreateOptionMenu(parent, name, ARGLIST);
  593.     XtManageChild(optionRC);
  594.     if ((optionLabel = XtNameToWidget(optionRC, "OptionLabel")) != NULL)
  595.         XtUnmanageChild(optionLabel);
  596.  
  597.     /*
  598.      * If we asked for list of buttons, provide it
  599.      */
  600.     if (blistp) {
  601.     STARTARGS;
  602.     SETARG(XmNchildren, blistp);
  603.     XtGetValues(menuPane, ARGLIST);
  604.     }
  605.  
  606.     return optionRC;
  607. }
  608.  
  609.  
  610. /**************************************************************************
  611.  *
  612.  * Function: makeLabeledRC
  613.  *
  614.  * Description: Creates a RowColumn with a left side label. This function
  615.  *    assumes that the RowColumn's parent is a Form widget. The label
  616.  *    widget created will be named <name> and the RowColumn will be
  617.  *    name <name>RC.
  618.  *
  619.  * Parameters: 
  620.  *    name (I) - name for label of RowColumn. Name of RowColumn itself
  621.  *                is <name>RC.
  622.  *    parent (I) - parent widget ID
  623.  *    topWidget (I) - top widget to which the RowColumn should be attached.
  624.  *                If NULL is specified the widget is attached to
  625.  *                the top of the form.
  626.  *
  627.  * Return: Widget ID of RowColumn.
  628.  *
  629.  **************************************************************************/
  630.  
  631. Widget makeLabeledRC(char *name, Widget parent, Widget topWidget)
  632. {
  633.     Widget rc;
  634.     char *rcName;
  635.     DEFARGS(15);
  636.  
  637.     /*
  638.      * Form the option RowColumn instance name
  639.      */
  640.     rcName = (char*)XtMalloc(strlen(name) + 10);
  641.     sprintf(rcName, "%sRC", name);
  642.  
  643.     /*
  644.      * Create the option RowColumn
  645.      */
  646.     STARTARGS;
  647.     SETARG(XmNorientation, XmHORIZONTAL);
  648.     SETARG(XmNpacking, XmPACK_TIGHT);
  649.     SETARG(XmNspacing, LABEL_FIELD_SPACE);
  650.     SETARG(XmNmarginWidth, 0);
  651.     SETARG(XmNmarginHeight, 1);
  652.     SETARG(XmNleftAttachment, XmATTACH_FORM);
  653.     if (topWidget) {
  654.         SETARG(XmNtopAttachment, XmATTACH_WIDGET);
  655.         SETARG(XmNtopWidget, topWidget);
  656.     } else {
  657.         SETARG(XmNtopAttachment, XmATTACH_FORM);
  658.     }
  659.     rc = XtCreateManagedWidget(rcName, xmRowColumnWidgetClass,
  660.                 parent, ARGLIST);
  661.  
  662.     /*
  663.      * Free allocated resources
  664.      */
  665.     XtFree(rcName);
  666.  
  667.     /*
  668.      * Create the option label. Note that we put OPT_TITLE_ID in the
  669.      * userData resource of the title label. This is so that when we
  670.      * call alignOptions the label is detected as the title.
  671.      */
  672.     STARTARGS;
  673.     SETARG(XmNuserData, (XtPointer)OPT_TITLE_ID);
  674.     XtCreateManagedWidget(name, xmLabelWidgetClass, rc, ARGLIST);
  675.  
  676.     return rc;
  677. }
  678.  
  679.  
  680. /**************************************************************************
  681.  *
  682.  * Function: makeLabeledForm
  683.  *
  684.  * Description: Creates a Form with a left side label. This function
  685.  *    assumes that the RowColumn's parent is a Form widget. The label
  686.  *    widget created will be named <name> and the Form will be
  687.  *    name <name>Form.
  688.  *
  689.  * Parameters: 
  690.  *    name (I) - name for label of Form. Name of Form itself is <name>Form.
  691.  *    parent (I) - parent widget ID
  692.  *    topWidget (I) - top widget to which the Form should be attached.
  693.  *                If NULL is specified the widget is attached to
  694.  *                the top of the form.
  695.  *    labelWidgetp (O) - label widget created for the form.
  696.  *
  697.  * Return: Widget ID of Form.
  698.  *
  699.  **************************************************************************/
  700.  
  701. Widget makeLabeledForm(char *name, Widget parent, Widget topWidget,
  702.                         Widget *labelWidgetp)
  703. {
  704.     Widget form;
  705.     char *formName;
  706.     DEFARGS(15);
  707.  
  708.     /*
  709.      * Form the option Form instance name
  710.      */
  711.     formName = (char*)XtMalloc(strlen(name) + 10);
  712.     sprintf(formName, "%sForm", name);
  713.  
  714.     /*
  715.      * Create the option Form
  716.      */
  717.     STARTARGS;
  718.     SETARG(XmNmarginWidth, 0);
  719.     SETARG(XmNleftAttachment, XmATTACH_FORM);
  720.     if (topWidget) {
  721.         SETARG(XmNtopAttachment, XmATTACH_WIDGET);
  722.         SETARG(XmNtopWidget, topWidget);
  723.     } else {
  724.         SETARG(XmNtopAttachment, XmATTACH_FORM);
  725.     }
  726.     form = XtCreateManagedWidget(formName, xmFormWidgetClass, parent, ARGLIST);
  727.  
  728.     /*
  729.      * Free allocated resources
  730.      */
  731.     XtFree(formName);
  732.  
  733.     /*
  734.      * Create the option label. Note that we put OPT_TITLE_ID in the
  735.      * userData resource of the title label. This is so that when we
  736.      * call alignOptions the label is detected as the title.
  737.      */
  738.     STARTARGS;
  739.     SETARG(XmNuserData, (XtPointer)OPT_TITLE_ID);
  740.     *labelWidgetp = XtCreateManagedWidget(name, xmLabelWidgetClass,
  741.                             form, ARGLIST);
  742.  
  743.     return form;
  744. }
  745.  
  746.  
  747. /**************************************************************************
  748.  *
  749.  * Function: HelpCB
  750.  *
  751.  * Description: Callback to display help text.
  752.  *
  753.  * Return: none
  754.  *
  755.  **************************************************************************/
  756.  
  757.  
  758. void HelpCB(Widget w, char *clientData, XEvent *event)
  759. {
  760.     switch(event->type)
  761.     {
  762.     case EnterNotify:
  763.                 XtVaSetValues(helpPane, XmNvalue, clientData, NULL);
  764.                 break;
  765.     case LeaveNotify:
  766. /*
  767.                 XtVaSetValues(helpPane, XmNvalue, "", NULL);
  768. */
  769.                 break;
  770.     }
  771. }
  772.  
  773.  
  774. /**************************************************************************
  775.  *
  776.  * Function: alignOptions
  777.  *
  778.  * Description: Aligns options such that their labels are right justified.
  779.  *    The alignment is performed by obtaining the children of the
  780.  *    specified parent widget. If is assumed that the parent widget is
  781.  *    a Form and the children are manager widgets that have been left
  782.  *    attached using the offset attachment constraint. The function looks
  783.  *    for a title label child in each option manager widget. The title
  784.  *    label is  identified by having its user data resource set to
  785.  *    OPT_TITLE_ID. If this label is not found, the first label found will
  786.  *    be considered the title label.
  787.  *
  788.  * Parameters: 
  789.  *    parentForm (I) - widget ID of Form parent
  790.  *
  791.  * Return: none
  792.  *
  793.  **************************************************************************/
  794.  
  795. void alignOptions(Widget parentForm)
  796. {
  797.     WidgetList optionMgrs, optionItems;
  798.     Widget label;
  799.     Widget action;
  800.     char *str;
  801.     register int i, j;
  802.     int numMgrs, numItems, titleID;
  803.     Dimension *widths, height;
  804.     Dimension maxWidth = 0;
  805.     static XmFontList fontlist;
  806.     DEFARGS(10);
  807.  
  808.     /*
  809.      * If first time through, create a dummy label so we can get its
  810.      * fontlist.
  811.      */
  812.     if (!fontlist) {
  813.     Widget lbl = XtCreateWidget("dummy", xmLabelWidgetClass, 
  814.                     parentForm, NULL, 0);
  815.         STARTARGS;
  816.         SETARG(XmNfontList, &fontlist);
  817.         XtGetValues(lbl, ARGLIST);
  818.     XtDestroyWidget(lbl);
  819.     }
  820.  
  821.     /*
  822.      * Get the manager children of the parent Form
  823.      */
  824.     STARTARGS;
  825.     SETARG(XmNnumChildren, &numMgrs);
  826.     SETARG(XmNchildren, &optionMgrs);
  827.     XtGetValues(parentForm, ARGLIST);
  828.  
  829.     /*
  830.      * Allocate an array for the label widths
  831.      */
  832.     widths = (Dimension*)XtMalloc(numMgrs * sizeof(Dimension));
  833.  
  834.     /*
  835.      * Cycle through each option manager and find its label widget.
  836.      */
  837.     for (i = 0; i < numMgrs; i++) {
  838.     /*
  839.      * If this child is not a manager, forget it
  840.      */
  841.     if (XtIsComposite(optionMgrs[i]) == False)
  842.         continue;
  843.  
  844.  
  845.     /*
  846.      * Get option items
  847.      */
  848.         STARTARGS;
  849.         SETARG(XmNnumChildren, &numItems);
  850.         SETARG(XmNchildren, &optionItems);
  851.         XtGetValues(optionMgrs[i], ARGLIST);
  852.  
  853.     /*
  854.      * Find label widget
  855.      */
  856.     label = NULL;
  857.     for (j = 0; j < numItems; j++) {
  858.         if (XtIsSubclass(optionItems[j], xmLabelWidgetClass)) {
  859.         if (!label)
  860.             label = optionItems[j];
  861.         STARTARGS;
  862.         SETARG(XmNuserData, &titleID);
  863.         XtGetValues(optionItems[j], ARGLIST);
  864.         if (titleID == OPT_TITLE_ID) {
  865.             label = optionItems[j];
  866.             break;
  867.         }
  868.         }
  869.     }
  870.     if (!label)
  871.         continue;
  872.  
  873.     /*
  874.      * Get the width of the title and update the maximum
  875.      * width value.
  876.      */
  877.     STARTARGS;
  878.     SETARG(XmNlabelString, &str);
  879.     XtGetValues(label, ARGLIST);
  880.     XmStringExtent(fontlist, str, &widths[i], &height);
  881.     if (widths[i] > maxWidth)
  882.         maxWidth = widths[i];
  883.     XtFree(str);
  884.  
  885.         /*
  886.          * Add a callback to display a short help message whenever the
  887.          * pointer is focused on the widget.
  888.          */
  889.  
  890.         if (helpPane != NULL) {
  891.            str=GetResourceString(label,"helpString",(char*) XtName(label),"");
  892.  
  893.            XtAddEventHandler(optionMgrs[i], (EventMask) 
  894.                             (EnterWindowMask|LeaveWindowMask),
  895.                             False, (XtEventHandler) HelpCB, str);
  896.         }
  897.  
  898.     }
  899.  
  900.  
  901.     /*
  902.      * Now align the options
  903.      */
  904.     for (i = 0; i < numMgrs; i++) {
  905.     /*
  906.      * If this child is not a manager, forget it
  907.      */
  908.     if (XtIsComposite(optionMgrs[i]) == False)
  909.         continue;
  910.  
  911.     /*
  912.      * Set the left offset
  913.      */
  914.         STARTARGS;
  915.         SETARG(XmNleftOffset, OPTIONS_INDENT + maxWidth - widths[i]);
  916.         XtSetValues(optionMgrs[i], ARGLIST);
  917.     }
  918.  
  919.     /*
  920.      * Free the width array
  921.      */
  922.     XtFree((char*)widths);
  923.  
  924. }
  925.  
  926.  
  927.  
  928. /**************************************************************************
  929.  *
  930.  * Function: loadList
  931.  *
  932.  * Description: Loads the specified scrolled list object with the specified
  933.  *    list of strings.
  934.  *
  935.  * Parameters: 
  936.  *    widget (I) - ID of a list widget
  937.  *    items (I) - list items
  938.  *    numItems (I) - number of items
  939.  *    incr (I) - amount to increment through the label list. This allows us
  940.  *            to pass arrays of structures and access the string
  941.  *            members.
  942.  *
  943.  * Return: none
  944.  *
  945.  **************************************************************************/
  946.  
  947. void loadList(Widget widget, char **items, register int numItems,
  948.             register int incr)
  949. {
  950.     register int i, offset;
  951.     XmString *listItems;
  952.     DEFARGS(5);
  953.  
  954.     /*
  955.      * Convert the list of strings into a list of Motif
  956.      * compound strings
  957.      */
  958.     listItems = (XmString*)XtMalloc(numItems * sizeof(XmString));
  959.     for (i = 0, offset = 0; i < numItems; i++, offset += incr)
  960.         listItems[i] = XmStringCreateSimple(*(char**)((paddr_t)items+offset));
  961.  
  962.     /*
  963.      * Set the compound string list into the list widget
  964.      */
  965.     STARTARGS;
  966.     SETARG(XmNitems, listItems);
  967.     SETARG(XmNitemCount, numItems);
  968.     XtSetValues(widget, ARGLIST);
  969.  
  970.     /*
  971.      * Free all allocated storage
  972.      */
  973.     for (i = 0; i < numItems; i++)
  974.     XmStringFree(listItems[i]);
  975.     XtFree((char*)listItems);
  976. }
  977.  
  978.  
  979. /**************************************************************************
  980.  *
  981.  * Function: getLabelFontlist
  982.  *
  983.  * Description: Returns the fontlist to use for label widgets that are
  984.  *    not major titles. We get the toggle button font and return that
  985.  *    as the proper font for minor object labels. Minor object labels
  986.  *    are things like unit labels (in., cm., %, etc.).
  987.  *
  988.  * Parameters:
  989.  *    w (I) - any instantiated manager widget ID
  990.  *
  991.  * Return: Fontlist for the label
  992.  *
  993.  **************************************************************************/
  994.  
  995. XmFontList getLabelFontlist(Widget w)
  996. {
  997.     static XmFontList fontlist = NULL;
  998.  
  999.     if (!fontlist) {
  1000.     DEFARGS(5);
  1001.  
  1002.         Widget dummy = XtCreateWidget("dummy", xmPushButtonWidgetClass,
  1003.                                         w, NULL, 0);
  1004.         STARTARGS;
  1005.         SETARG(XmNfontList, &fontlist);
  1006.         XtGetValues(dummy, ARGLIST);
  1007.         XtDestroyWidget(dummy);
  1008.     }
  1009.     return fontlist;
  1010. }
  1011.  
  1012.  
  1013. /**************************************************************************
  1014.  *
  1015.  * Function: intVerifyCB
  1016.  *
  1017.  * Description: Used as a verify called for text fields which accept
  1018.  *    integers. The routine will disallow everything except
  1019.  *    an empty text field, the digits 0-9 or if the specified range
  1020.  *    permits, '-' and '+'. The numerical value of the input is not
  1021.  *    checked against the specified range. This is done using the
  1022.  *    intValueCB. If the range structure pointer is NULL, no sign
  1023.  *    checking is performed.
  1024.  *
  1025.  * Parameters: 
  1026.  *    w (I) - widget which triggered this callback
  1027.  *    clientData (I) - min/max value struct
  1028.  *    callData (I) - text verify callback
  1029.  *
  1030.  * Return: none
  1031.  *
  1032.  **************************************************************************/
  1033. /* ARGSUSED */
  1034.  
  1035. void intVerifyCB(Widget w, XtPointer clientData, XtPointer callData)
  1036. {
  1037.     register int i, len;
  1038.     register char ch;
  1039.     char *newStr;
  1040.     Position pos;
  1041.     XmTextVerifyCallbackStruct *verify = (XmTextVerifyCallbackStruct*)callData;
  1042.     Irange *range = (Irange*)clientData;
  1043.  
  1044.     /*
  1045.      * Assume allowed
  1046.      */
  1047.     verify->doit = True;
  1048.  
  1049.     /*
  1050.      * Check for empty case
  1051.      */
  1052.     if (verify->text->ptr == NULL || verify->text->length == 0) {
  1053.         verify->text->ptr = XtNewString("");
  1054.         return;
  1055.     }
  1056.  
  1057.     /*
  1058.      * Check for invalid characters
  1059.      */
  1060.     len = verify->text->length;
  1061.     newStr = (char*)XtCalloc(len + 10, sizeof(char));
  1062.     (void)strncpy(newStr, verify->text->ptr, len);
  1063.     for (i = 0, pos = verify->startPos; i < len; i++, pos++) {
  1064.         ch = newStr[i];
  1065.         if (!isdigit((int)ch) && ch != '-' && ch != '+') {
  1066.             verify->doit = False;
  1067.         break;
  1068.     }
  1069.     if ((ch == '-' || ch == '+') && pos) {
  1070.             verify->doit = False;
  1071.         break;
  1072.     }
  1073.     }
  1074.  
  1075.     /*
  1076.      * If a range was specified, use its signs to determine if '+' or
  1077.      * '-' should be allowed
  1078.      */
  1079.     if (range && verify->doit && len) {
  1080.     if (range->min > range->max)
  1081.         verify->doit = False;
  1082.     else if (range->min >= 0 && strchr(newStr, '-'))
  1083.         verify->doit = False;
  1084.     else if (range->max < 0 && strchr(newStr, '+'))
  1085.         verify->doit = False;
  1086.     }
  1087.     XtFree((char*)newStr);
  1088. }
  1089.  
  1090.  
  1091. /**************************************************************************
  1092.  *
  1093.  * Function: intValueCB
  1094.  *
  1095.  * Description: Verifies that the text field entry falls within the specified
  1096.  *    range. If a value is out of range the closest point in the range
  1097.  *    replaces the entered value.
  1098.  *
  1099.  * Parameters: 
  1100.  *    w (I) - widget which triggered this callback
  1101.  *    clientData (I) - min/max value struct
  1102.  *    callData (I) - any callback
  1103.  *
  1104.  * Return: none
  1105.  *
  1106.  **************************************************************************/
  1107. /* ARGSUSED */
  1108.  
  1109. void intValueCB(Widget w, XtPointer clientData, XtPointer callData)
  1110. {
  1111.     Irange *range = (Irange*)clientData;
  1112.     char *str, buf[50];
  1113.     int val;
  1114.  
  1115.     str = XmTextFieldGetString(w);
  1116.     if (*str) {
  1117.     val = atoi(str);
  1118.     if (val < range->min) {
  1119.         (void)sprintf(buf, "%d", range->min);
  1120.         XmTextFieldSetString(w, buf);
  1121.     } else if (val > range->max) {
  1122.         (void)sprintf(buf, "%d", range->max);
  1123.         XmTextFieldSetString(w, buf);
  1124.     }
  1125.     }
  1126.     XtFree((char*)str);
  1127. }
  1128.  
  1129.  
  1130. /**************************************************************************
  1131.  *
  1132.  * Function: floatVerifyCB
  1133.  *
  1134.  * Description: Used as a verify called for text fields which accept
  1135.  *    floating point values. The routine will disallow everything except
  1136.  *    an empty text field, the digits 0-9, the '.', or if the specified range
  1137.  *    permits, '-' and '+'. The numerical value of the input is not
  1138.  *    checked against the specified range. If the range structure pointer
  1139.  *    is NULL, no sign checking is performed.
  1140.  *
  1141.  * Parameters: 
  1142.  *    w (I) - widget which triggered this callback
  1143.  *    clientData (I) - min/max value struct
  1144.  *    callData (I) - text verify callback
  1145.  *
  1146.  * Return: none
  1147.  *
  1148.  **************************************************************************/
  1149. /* ARGSUSED */
  1150.  
  1151. void floatVerifyCB(Widget w, XtPointer clientData, XtPointer callData)
  1152. {
  1153.     register int i, len;
  1154.     register char ch;
  1155.     char *newStr;
  1156.     Position pos;
  1157.     XmTextVerifyCallbackStruct *verify = (XmTextVerifyCallbackStruct*)callData;
  1158.     Frange *range = (Frange*)clientData;
  1159.  
  1160.     /*
  1161.      * Assume allowed
  1162.      */
  1163.     verify->doit = True;
  1164.  
  1165.     /*
  1166.      * Check for empty case
  1167.      */
  1168.     if (verify->text->ptr == NULL || verify->text->length == 0) {
  1169.         verify->text->ptr = XtNewString("");
  1170.         return;
  1171.     }
  1172.  
  1173.     /*
  1174.      * Test for invalid characters
  1175.      *
  1176.      * XXX - should not allow multiple '.'
  1177.      */
  1178.     len = verify->text->length;
  1179.     newStr = (char*)XtCalloc(len + 10, sizeof(char));
  1180.     (void)strncpy(newStr, verify->text->ptr, len);
  1181.     for (i = 0, pos = verify->startPos; i < len; i++, pos++) {
  1182.         ch = newStr[i];
  1183.         if (!isdigit((int)ch) && ch != '-' && ch != '+' && ch != '.') {
  1184.             verify->doit = False;
  1185.         break;
  1186.     }
  1187.     if ((ch == '-' || ch == '+') && pos) {
  1188.             verify->doit = False;
  1189.         break;
  1190.     }
  1191.     }
  1192.  
  1193.     /*
  1194.      * Test for invalid '-' and '+' 
  1195.      */
  1196.     if (range && verify->doit && len) {
  1197.     if (range->min > range->max)
  1198.         verify->doit = False;
  1199.     else if (range->min >= 0.0 && strchr(newStr, '-'))
  1200.         verify->doit = False;
  1201.     else if (range->max < 0.0 && strchr(newStr, '+'))
  1202.         verify->doit = False;
  1203.     }
  1204.     XtFree((char*)newStr);
  1205. }
  1206.  
  1207.  
  1208. /**************************************************************************
  1209.  *
  1210.  * Function: findStr
  1211.  *
  1212.  * Description: Searches an array of strings for the specified string.
  1213.  *    Currently the search is linear.
  1214.  *
  1215.  * Parameters: 
  1216.  *    array (I) - array of strings. Can be a structure with the
  1217.  *            incr parameter set appropriately.
  1218.  *    len (I) - number of entries in array.
  1219.  *    str (I) - string for which to search.
  1220.  *    incr (I) - amount to increment through the array. This allows us
  1221.  *            to pass arrays of structures and access the string
  1222.  *            members.
  1223.  *
  1224.  * Return: Returns the array index of the matched string if found or
  1225.  *    -1 if not found.
  1226.  *
  1227.  **************************************************************************/
  1228.  
  1229. int findStr(char **array, int len, char *str, int incr)
  1230. {
  1231.     register int i, offset, pos = -1;
  1232.  
  1233.     for (i = 0, offset = 0; i < len; i++, offset += incr) {
  1234.     if (!strcmp(*(char**)((paddr_t)array + offset), str)) {
  1235.         pos = i;
  1236.         break;
  1237.     }
  1238.     }
  1239.  
  1240.     return pos;
  1241. }
  1242.  
  1243.  
  1244. /**************************************************************************
  1245.  *
  1246.  * Function: buildOpts
  1247.  *
  1248.  * Description: Builds an options string. This is nothing more than a
  1249.  *    routine which appends the specified string onto the end of a
  1250.  *    given string. A space separates the origanl string and the appended
  1251.  *    string. This routine allocates storage for the new string.
  1252.  *
  1253.  * Parameters: 
  1254.  *    origStrp (O) - pointer to the original string. Must point to
  1255.  *            NULL the first time through.
  1256.  *    newStr (I) - string to append to origStrp.
  1257.  *
  1258.  * Return: none
  1259.  *
  1260.  **************************************************************************/
  1261.  
  1262. void buildOpts(char **origStrp, const char *newStr)
  1263. {
  1264.     register int len, origLen;
  1265.  
  1266.     if (!*origStrp)
  1267.         *origStrp = XtNewString(newStr);
  1268.     else {
  1269.     origLen = strlen(*origStrp);
  1270.         len = origLen + strlen(newStr) + 5;
  1271.         *origStrp = (char*)XtRealloc(*origStrp, len);
  1272.     (void)sprintf(*origStrp + origLen, " %s", newStr);
  1273.     }
  1274. }
  1275.  
  1276.  
  1277. /**************************************************************************
  1278.  *
  1279.  * Function: makeOpt
  1280.  *
  1281.  * Description: Constructs a string consisting of a '-', an option switch
  1282.  *    and any arguments that the switch might take.
  1283.  *
  1284.  * Parameters: 
  1285.  *    name (I) - name of option switch as it should appear on a printer
  1286.  *            specific option command-line.
  1287.  *    args... (I) - parameter list of arguments, Must be NULL terminated.
  1288.  *
  1289.  * Return: String for the option. Storage is allocate by the function
  1290.  *    and should be freed by the caller when no longer needed. Free
  1291.  *    using the XtFree function.
  1292.  *
  1293.  **************************************************************************/
  1294. /* VARARGS */
  1295.  
  1296. char *makeOpt(char *name, ...)
  1297. {
  1298.     va_list args;
  1299.     char *optStr, *aptr;
  1300.  
  1301.     optStr = (char*)XtMalloc(strlen(name) + 5);
  1302.     (void)sprintf(optStr, "-%s", name);
  1303.     va_start(args, name);
  1304.     while ((aptr = (char*)va_arg(args, char*)) != NULL) {
  1305.         optStr = (char*)XtRealloc(optStr, strlen(optStr) + strlen(aptr) + 5);
  1306.     (void)strcat(optStr, " ");
  1307.     (void)strcat(optStr, aptr);
  1308.     }
  1309.     va_end(args);
  1310.  
  1311.     return optStr;
  1312. }
  1313.  
  1314.  
  1315. /**************************************************************************
  1316.  *
  1317.  * Function: setTextFSensitivity
  1318.  *
  1319.  * Description: Sets the sensitivity of the specified text field widget
  1320.  *    and changes the widget's background to the appropriate color.
  1321.  *
  1322.  * Parameters: 
  1323.  *    widget (I) - ID of text field widget
  1324.  *    state (I) - True if sensitive, False otherwise
  1325.  *
  1326.  * Return: none
  1327.  *
  1328.  **************************************************************************/
  1329.  
  1330. void setTextFSensitivity(Widget widget, Boolean state)
  1331. {
  1332.     static Boolean firstTime = True;
  1333.     static GUIColor sensColor;
  1334.     static GUIColor insensColor;
  1335.     static Colormap colormap;
  1336.     GUIColor *color;
  1337.     DEFARGS(5);
  1338.  
  1339.     /*
  1340.      * We only need to do this first part once, when we are
  1341.      * first called. We need to determine what the sensitive
  1342.      * background color is and determine shadow colors for
  1343.      * both the sensitive and insensitive cases.
  1344.      */
  1345.     if (firstTime) {
  1346.         /*
  1347.          * Get the sensitive background color of a representative
  1348.          * field widget
  1349.          */
  1350.     STARTARGS;
  1351.         SETARG(XmNforeground, &sensColor.foreground);
  1352.         SETARG(XmNbackground, &sensColor.background);
  1353.         SETARG(XmNcolormap, &colormap);
  1354.         XtGetValues(widget, ARGLIST);
  1355.  
  1356.         /*
  1357.          * Compute the text field shadow colors
  1358.          * for the sensitive and insensitive states
  1359.          */
  1360.         XmGetColors(XtScreen(widget), colormap, sensColor.background, NULL,
  1361.                     &sensColor.tshadow, &sensColor.bshadow, NULL);
  1362.     insensColor.foreground = gmodelResources.insensitiveFore;
  1363.     insensColor.background = gmodelResources.insensitiveBack;
  1364.         XmGetColors(XtScreen(widget), colormap, insensColor.background, NULL,
  1365.                     &insensColor.tshadow, &insensColor.bshadow, NULL);
  1366.  
  1367.     firstTime = False;
  1368.     }
  1369.  
  1370.     /*
  1371.      * Set the text field sensitivity and set the
  1372.      * appropriate colors
  1373.      */
  1374.     XtSetSensitive(widget, state);
  1375.     color = (state)? &sensColor: &insensColor;
  1376.     STARTARGS;
  1377.     SETARG(XmNforeground, color->foreground);
  1378.     SETARG(XmNbackground, color->background);
  1379.     SETARG(XmNtopShadowColor,color->tshadow);
  1380.     SETARG(XmNbottomShadowColor, color->bshadow);
  1381.     XtSetValues(widget, ARGLIST);
  1382. }
  1383.  
  1384.  
  1385. /**************************************************************************
  1386.  *
  1387.  * Function: setListSensitivity
  1388.  *
  1389.  * Description: Sets the sensitivity of the specified list widget
  1390.  *    and changes the widget's foreground to the appropriate color.
  1391.  *
  1392.  * Parameters: 
  1393.  *    widget (I) - ID of list widget
  1394.  *    state (I) - True if sensitive, False otherwise
  1395.  *
  1396.  * Return: none
  1397.  *
  1398.  **************************************************************************/
  1399.  
  1400. void setListSensitivity(Widget widget, Boolean state)
  1401. {
  1402.     static Boolean firstTime = True;
  1403.     static GUIColor sensColor;
  1404.     static GUIColor insensColor;
  1405.     GUIColor *color;
  1406.     DEFARGS(5);
  1407.  
  1408.     /*
  1409.      * We only need to do this first part once, when we are
  1410.      * first called. We need to determine what the sensitive
  1411.      * background color is and determine shadow colors for
  1412.      * both the sensitive and insensitive cases.
  1413.      */
  1414.     if (firstTime) {
  1415.         /*
  1416.          * Get the sensitive colors of a sensitive widget
  1417.          */
  1418.     STARTARGS;
  1419.         SETARG(XmNforeground, &sensColor.foreground);
  1420.         XtGetValues(widget, ARGLIST);
  1421.     insensColor.foreground = gmodelResources.insensitiveFore;
  1422.     firstTime = False;
  1423.     }
  1424.  
  1425.     /*
  1426.      * Set the list sensitivity and set the appropriate colors
  1427.      */
  1428.     XtSetSensitive(widget, state);
  1429.     color = (state)? &sensColor: &insensColor;
  1430.     STARTARGS;
  1431.     SETARG(XmNforeground, color->foreground);
  1432.     XtSetValues(widget, ARGLIST);
  1433. }
  1434.  
  1435. /**************************************************************************
  1436.  *
  1437.  * Function: getHalftoneScreens
  1438.  *
  1439.  * Description: Gets a list of screens from the resource file.
  1440.  *
  1441.  * Parameters:
  1442.  *
  1443.  * Return: number of halftones parsed
  1444.  *
  1445.  **************************************************************************/
  1446. int getHalftoneScreens(Widget parent, char *printername, char **halftoneLbl)
  1447. {
  1448.  
  1449.     int count;
  1450.     int len;
  1451.     int ii;
  1452.     char screenName[MAX_HALFTONE_CHAR_SIZE];
  1453.     char *str;
  1454.     char *tptr;
  1455.  
  1456.     count = 0;
  1457.  
  1458.     /* Get the screens common to all printers */
  1459.  
  1460.     str=GetResourceString(parent,"CommonScreens", (char*) XtName(parent),"");
  1461.     if (!str) return count;
  1462.  
  1463.     /* The screen names are seperated by commas, parse em */
  1464.  
  1465.     tptr=str;
  1466.     while ((halftoneLbl[count] = strtok(tptr,",")) != NULL) {
  1467.        tptr=NULL;
  1468.        count++;
  1469.        if (count == MAX_HALFTONE_SCREENS) return count ;
  1470.     }
  1471.  
  1472.     /* There can also be screens specific to a printer model.  Get hose */
  1473.  
  1474.     if (!printername) return count;   /* Make sure this valid before using */
  1475.  
  1476.     str=GetResourceString(parent,screenName, (char*) XtName(parent),"");
  1477.  
  1478.     /* The resource name is the printer name with _Screens appended (printer 
  1479.      * name comes from the NAME= field in the model file.  We replace blanks 
  1480.      * with underscores.
  1481.      */
  1482.  
  1483.     (void) strncpy(screenName,printername,MAX_HALFTONE_CHAR_SIZE);
  1484.  
  1485.     (void) strncat(screenName,"_Screens",
  1486.                                MAX_HALFTONE_CHAR_SIZE-strlen(screenName));
  1487.     len=strlen(screenName);
  1488.     for (ii=0;ii<len;ii++) {
  1489.        if (screenName[ii]==' ') screenName[ii]='_';
  1490.     }
  1491.  
  1492.     /* Now get the screens and parse them adding to our list. */
  1493.  
  1494.     str=GetResourceString(parent,screenName, (char*) XtName(parent),"");
  1495.     tptr=str;
  1496.     while ((halftoneLbl[count]  = strtok(tptr,",")) != NULL) {
  1497.        tptr=NULL;
  1498.        count++;
  1499.        if (count == MAX_HALFTONE_SCREENS) return count ;
  1500.     }
  1501.  
  1502.     return count; 
  1503.    
  1504. }
  1505.